/****************************************************************************
Copyright (c) 2010-2013 cocos2d-x.org
Copyright (c) Microsoft Open Technologies, Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#include "MainGameScene.h"
#include "GameDimensions.h"
#include "AppDelegate.h"
#include "UserScores.h"
#include "GameModel.h"


bool MainGameScene::useSaved=false;

MainGameScene::MainGameScene():MyScene()
{
}

MainGameScene::~MainGameScene()
{
    //dtor
    if(NULL!=_model)
    {
        delete _model;
    }
}

void MainGameScene::gameStepIncrease(){
    useStep++;
    //
    if(NULL!=lstep){
        char text[20];
        sprintf(text,"STEP:%d",useStep);
        lstep->setString(text,true);
    }
}


void MainGameScene::gameTimerCallback(float t){
    useTime++;
    //
    if(NULL!=ltime){
        char text[20];
        sprintf(text,"TIME:%02d:%02d",useTime/60,useTime%60);
        ltime->setString(text,true);
    }
}





bool MainGameScene::init()
{
    //generate model
    if(useSaved){
        loadGameStat();
    }else{
        //load data
        CCUserDefault* save=CCUserDefault::sharedUserDefault();
        int lastgs=save->getIntegerForKey("game_diff");
        if(lastgs<3){
            lastgs=3;
        }
        //generate picture path.
        srand(unsigned(time(0)));
        picId=rand()%GameDimensions::PicCount;

        _model=new GameModel(lastgs);
        _model->random(200*lastgs);
        //print the game board.
        CCLog("model==%s",_model->toString().c_str());

        useStep=0;
        useTime=0;
        diff=lastgs;

    }

    // Get global dimensions
    AppDelegate* app=AppDelegate::getApplication();
    const GameDimensions* gameDimension=app->getGameDimensions();
    //CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

    int x0=gameDimension->gwLeft+ origin.x,
    y0=gameDimension->gwTop+ origin.y;
    //    int w=gameDimension->width,h=gameDimension->height;
    //create background layer
    CCLayer *layer=CCLayerColor::create();
    //
    //Add head background
    CCSprite* shead=CCSprite::create("background-head.png");
    shead->setAnchorPoint(ccp(0,1));
    shead->setPosition(ccp(gameDimension->gwLeft+ origin.x,gameDimension->height+ origin.y));
    layer->addChild(shead,0);

    //Add back menu
    CCLabelBMFont* lback=CCLabelBMFont::create("BACK","fonts/my-font.fnt");
    CCMenuItem* itemback=CCMenuItemLabel::create(lback,this,menu_selector(MainGameScene::menuBackCallback));
    itemback->setPosition(ccp(gameDimension->gameLabelBackCx,gameDimension->gameLabelBackCy));
    CCMenu* pMenu = CCMenu::create(itemback, NULL);
    pMenu->setPosition(CCPointZero);
    layer->addChild(pMenu, 1);

    addChild(layer,0);

    //Add step label
    lstep=CCLabelBMFont::create("","fonts/my-font.fnt");
    lstep->setPosition(ccp(gameDimension->gameLabelStepCx,gameDimension->gameLabelStepCy));
    lstep->setScale(0.75);
    lstep->setColor(ccc3(255,255,0));
    //
    layer->addChild(lstep,1);

    //Add time label
    ltime=CCLabelBMFont::create("","fonts/my-font.fnt");
    ltime->setPosition(ccp(gameDimension->gameLabelTimeCx,gameDimension->gameLabelTimeCy));
    ltime->setScale(0.75);
    ltime->setColor(ccc3(255,255,0));


    layer->addChild(ltime,1);

    drawDebugBox();

    //
    char pic[20];
    sprintf(pic,"pic%d.png",picId);

    //Show thumb
    CCSprite* thumb=CCSprite::create(pic/*,CCRect(0,0,480,480)*/);
    CCRect rc=thumb->getTextureRect();
    CCLog("pic texture %.0f x %.0f",rc.size.width,rc.size.height);
    float srcborder=rc.size.height;
    float rt=160.0/GameDimensions::PicSrcBorder;//gameDimension->ratio*160/480;
    thumb->setAnchorPoint(ccp(0,1));
    thumb->setScale(rt);
    thumb->setPosition(ccp(x0+5,y0+gameDimension->height-5));
    addChild(thumb,1);

    //Add game layer
    GameLayer* game=GameLayer::create();
    game->setPosition(ccp(origin.x+gameDimension->gameBoxLeft, origin.y+gameDimension->gameBoxTop));
    game->initModel(gameDimension->gameBoxBorder,srcborder,pic,_model);
    addChild(game,1);

    return true;
}

int MainGameScene::calcScore(int t,int mov,int dif,int mix){
    float at=0.7,am=0.3;
    float d2=dif*dif;
    float s=d2*60/t*at+d2*mix/mov*am;
    return (int)(s*500);
}

void MainGameScene::showWin(){
    //
    //
    unschedule(schedule_selector(MainGameScene::gameTimerCallback));
    score=calcScore(useTime,useStep,diff,100);//(int)((100*diff)/useStep*10000/useTime);
    //save score
    UserScores us;
    us.addNewRecord(diff,useStep,useTime,score);
    us.save();

    GameWinLayer* win=GameWinLayer::create();
    win->setGameResult(score,useStep,diff);

    addChild(win,4);

}

void MainGameScene::loadGameStat(){
    CCUserDefault* save=CCUserDefault::sharedUserDefault();
    int n=save->getIntegerForKey("game_size");
    string stat=save->getStringForKey("game_stat");
    int t=save->getIntegerForKey("game_time");
    int s=save->getIntegerForKey("game_step");
    int pic=save->getIntegerForKey("game_pic_id");
    //
    _model=new GameModel(n);
    bool res=_model->pushData(stat);


    useTime=t;
    useStep=s;
    if(pic>=0 && pic<GameDimensions::PicCount){
        picId=pic;
    }else{
        picId=0;
    }

    CCLog("load game %s",res?"ok":"false");
}

void MainGameScene::saveGameStat(){
    string stat=_model->pullData();

    CCUserDefault* save=CCUserDefault::sharedUserDefault();
    save->setIntegerForKey("game_size",3);
    save->setStringForKey("game_stat",stat);
    save->setIntegerForKey("game_time",useTime);
    save->setIntegerForKey("game_step",useStep);
    save->setIntegerForKey("game_pic_id",picId);
    //
    save->flush();

    CCLog("game data saved");
}

void MainGameScene::onExit(){
    //save game before exit;
    saveGameStat();
    MyScene::onExit();
}

void MainGameScene::onEnter(){
    //
    MyScene::onEnter();

    scheduleUpdate();
    schedule(schedule_selector(MainGameScene::gameTimerCallback),1);

    char str[20];
    sprintf(str,"STEP:%d",useStep);
    if(NULL!=lstep) lstep->setString(str,true);
}


void MainGameScene::menuBackCallback()
{
    backToMain();
    //CCDirector::sharedDirector()->popScene();

}


//GameWinLayer
bool GameWinLayer::init(){
    AppDelegate* app=AppDelegate::getApplication();
    const GameDimensions* gameDimension=app->getGameDimensions();
    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
    //Add background
    CCSprite* bk=CCSprite::create("background-win.png");
    bk->setPosition(ccp(origin.x+gameDimension->gwCx,origin.y+gameDimension->gwCy));
    addChild(bk,0);

    //Add labels
    const char* fnt="fonts/my-font.fnt";
    lscore=CCLabelBMFont::create("",fnt);
    lmove=CCLabelBMFont::create("",fnt);
    ldif=CCLabelBMFont::create("",fnt);
    int hl=(int)(60*gameDimension->ratio);
    int hb=gameDimension->gwCy-(int)(200*gameDimension->ratio)+hl;
    lscore->setPosition(ccp(origin.x+gameDimension->gwCx,origin.y+hb));
    lmove->setPosition(ccp(origin.x+gameDimension->gwCx,origin.y+hb+hl));
    ldif->setPosition(ccp(origin.x+gameDimension->gwCx,origin.y+hb+2*hl));
    lscore->setScale(0.5);
    lmove->setScale(0.5);
    ldif->setScale(0.5);
    addChild(lscore,1);
    addChild(lmove,1);
    addChild(ldif,1);

    return true;
}

void GameWinLayer::IncreaseScore(float dt){
    tmps++;
    if(tmps>20) return;
    int s=(int)(score/20.0*tmps);
    char text[20];
    sprintf(text,"Score: %d",s);
    //CCLog("s=%d",s);
    lscore->setString(text,true);

}

void GameWinLayer::onEnter(){
    CCLayer::onEnter();
    //
    //CCLog("win data: %d,%d,%d",difficulty,move,score);

    char txtdif[20];
    sprintf(txtdif,"Difficulty: %d",difficulty);
    ldif->setString(txtdif,true);

    char txtmove[20];
    sprintf(txtmove,"Move: %d",move);
    lmove->setString(txtmove,true);
    //
    tmps=0;
    scheduleUpdate();
    schedule(schedule_selector(GameWinLayer::IncreaseScore),0.1,20-1,0);
}

void GameWinLayer::setGameResult(int score,int move,int difficulty){
    this->score=score;
    this->move=move;
    this->difficulty=difficulty;
}

